﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace MassiveBattle.Controller
{
	public abstract partial class BaseController : MonoBehaviour, Manager.IWorker
	{
		#region Take Data
		protected IDictionary<string, EventlineTake> takeDic = new Dictionary<string, EventlineTake>();

		protected IEventlinePlayer takeCur;
		protected EMassTake takeTypeCur;

		public bool IsTakeIdle
		{
			get
			{
				return takeTypeCur == EMassTake.idle01 || takeTypeCur == EMassTake.idle02;
			}
		}
		public bool IsTakeSkill
		{
			get
			{
				return takeTypeCur == EMassTake.skill01;
			}
		}

		public event Action<BaseController> EventTakeEnd;
		#endregion

		#region Take
		public virtual void PlayTake(EMassTake takeType, UnityEngine.Object[] actorList, bool isLoop = false, EArea area = EArea.NONE)
		{
			StopTake();

			string takeName = takeType.ToString();

			if (takeDic.ContainsKey(takeName))
			{
				takeCur = Eventline.Play(takeDic[takeName], actorList, gameObject, isLoop);
				takeTypeCur = takeType;
			}
			else
				Debug.LogError("PlayTake fail. takeDic not have key  " + takeType + "   " + ModelGameObject.name);
		}

		protected void StopTake()
		{
			if (takeCur != null)
			{
				takeCur.Stop();
				takeCur = null;
			}

			takeTypeCur = EMassTake.Max;
		}

		protected void hit(object[] paramList)
		{
			if (TargetList == null)
				return;

			if (IsHealer)
			{
				int point = Utility.GetHealPoint(Manager, Stat, Target.Stat);

				Target.Heal(point);
			}
			else
			{
				int count = 1;

				if (paramList.Length >= 2)
				{
					if (!int.TryParse(paramList[1] as string, out count))
						count = 1;
				}

				if (!IsAlive)
					return;

				bool isSkill = IsSidePlayer && IsTakeSkill;

				foreach (var controller in TargetList)
					controller.Damage(Mathf.FloorToInt((float)PointDic[controller] / count), isSkill, this);
			}
		}

		protected void move(object[] paramList)
		{
			if (!IsTargetExist)
				return;

			if (IsCaster)
				return;

			var direction = paramList[0] as string;
			float time;

			if (!float.TryParse(paramList[1] as string, out time))
				time = 0.2f;

			if ("f".Equals(direction))
				LeanTween.move(ModelGameObject, BattleUtil.GetTargetAttackPos(ModelTransform.position, Target.ModelTransform.position, projectileMyRadius + Target.projectileMyRadius), time);
			else if ("b".Equals(direction))
				LeanTween.move(ModelGameObject, Position, time);
		}

		protected void supportatk() { }

		protected void supportdef() { }

		protected void cast()
		{
			Projectile(Target);
		}

		protected void guard() { }

		protected void cameraidle()
		{
			if (EventlineStaticActor.Camera != null)
			{
				if (EventlineStaticActor.Camera.transform.parent == pointCamera)
				{
					EventlineStaticActor.Camera.transform.parent = null;

					Manager.PlayNextTake();
				}
			}
		}

		protected void cameraidleinstant()
		{
			if (EventlineStaticActor.Camera != null)
			{
				if (EventlineStaticActor.Camera.transform.parent == pointCamera)
				{
					EventlineStaticActor.Camera.transform.parent = null;

					Manager.PlayNextTake(false);
				}
			}
		}

		//카메라 쉐이크 이후 middle카메라 원점으로 돌리기//
		protected void camerashakeclear()
		{
			EventlineStaticActor.MiddleCam.transform.localPosition = Vector3.zero;
			EventlineStaticActor.MiddleCam.transform.localRotation = Quaternion.identity;
			EventlineStaticActor.MiddleCam.transform.localScale = Vector3.one;
		}

		protected void end(object param) { }

		protected virtual void EndOfPlay(IEventlinePlayer param)
		{
			if (param != takeCur)
				return;

			if (FsmMain.StateCurrent != null && FsmMain.StateCurrent.EventTakeEnd != null)
				FsmMain.StateCurrent.EventTakeEnd();

			if (EventTakeEnd != null)
				EventTakeEnd(this);
		}
		#endregion
	}
}
